package top.infopub.httpclient.cmpt;


import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.cookie.Cookie;
import org.apache.http.message.BasicNameValuePair;

import top.infopub.httpclient.base.HttpEnum;

import com.google.common.base.Joiner;


/**
 * HTTP 请求bean
 * @author Awoke
 * @version 2018年4月27日
 * @see Request
 * @since
 */
public class Request implements Serializable {

    private static final long serialVersionUID = 2378290839814065797L;

    private String url;

    private String method;

    private HttpEntity entity;

    // 默认 请求超时时间 15s
    private int timeout = 15 * 1000;

    private Map<String, String> headers;

    private boolean isFile = false;

    // 默认 编码
    private String entityCharset = "UTF-8";

    private List<NameValuePair> formParams = null;

    public Request() {}

    public Request(String url) {
        this.url = url;
    }

    public Request(String url, int timeout) {
        this.url = url;
        this.timeout = timeout;
    }

    public Request(String url, String method, HttpEntity entity, int timeout) {
        super();
        this.url = url;
        this.method = method;
        this.entity = entity;
        this.timeout = timeout;
    }

    public Request(String url, String method, HttpEntity entity) {
        super();
        this.url = url;
        this.method = method;
        this.entity = entity;
    }

    public Request(String url, String method, String entityCharset, HttpEntity entity) {
        super();
        this.url = url;
        this.method = method;
        this.entityCharset = entityCharset;
        this.entity = entity;
    }

    public Request(String url, String method) {
        super();
        this.url = url;
        this.method = method;
    }

    public Request addParam(String key, String value) {
        if (formParams == null) {
            formParams = new ArrayList<NameValuePair>();
        }
        method = HttpEnum.Method.POST.getMethod();
        formParams.add(new BasicNameValuePair(key, value));
        return this;
    }

    public HttpEntity getEntity() {
        if (entity == null && formParams != null) {
            try {
                entity = new UrlEncodedFormEntity(formParams, entityCharset);
            }
            catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return entity;
    }

    public void clearCookie() {
        if (headers == null) {
            return;
        }
        headers.remove(HttpEnum.Header.COOKIE.getProp());
    }

    public void addCookie(Cookie... cookie) {
        if (cookie == null) {
            return;
        }
        if (headers == null) {
            headers = new HashMap<String, String>();
        }
        String[] mappingCookies = new String[cookie.length];
        for (int i = 0; i < cookie.length; i++ ) {
            Cookie _c = cookie[i];
            mappingCookies[i] = _c.getName() + "=" + _c.getValue();
        }
        String _cookie = headers.get(HttpEnum.Header.COOKIE.getProp());
        String _newAdd = Joiner.on(";").join(mappingCookies);
        _cookie = StringUtils.isNoneBlank(_cookie) ? _cookie + ";" + _newAdd : _newAdd;
        headers.put(HttpEnum.Header.COOKIE.getProp(), _cookie);
    }

    public void addHeader(String name, String value) {
        if (headers == null) {
            headers = new HashMap<String, String>();
        }
        headers.put(name, value);
    }

    public int getTimeout() {
        return timeout;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    public void setEntity(HttpEntity entity) {
        this.entity = entity;
    }

    public String getUrl() {
        return url;
    }

    public Map<String, String> getHeaders() {
        return headers;
    }

    public void setHeaders(Map<String, String> headers) {
        this.headers = headers;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getMethod() {
        return method;
    }

    public void setMethod(String method) {
        this.method = method;
    }

    public List<NameValuePair> getFormParams() {
        return formParams;
    }

    public boolean isFile() {
        return isFile;
    }

    public void setFile(boolean isFile) {
        this.isFile = isFile;
    }

    public String getEntityCharset() {
        return entityCharset;
    }

    public void setEntityCharset(String entityCharset) {
        this.entityCharset = entityCharset;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Request request = (Request)o;

        if (!url.equals(request.url)) return false;

        return true;
    }

    @Override
    public int hashCode() {
        return url.hashCode();
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }
}
